﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using ITProject.Domain.Entities;

namespace ITProject.WebUI.Models.ProjectAdmin
{
    public class ProjectAdminAddNewFunctionalRequirement
    {
        [Required(ErrorMessage = "Nazwa wymagania jest wymagana")]
        [MinLength(4,ErrorMessage="Nazwa wymagania musi zawierać conajmniej 4 znaki")]
        [Display(Name="Nazwa")]
        public string Name { get; set; }

        [Display(Name = "Aktorzy")]
        public string Actors { get; set; }
        
        private PriorityViewModel pvm = new PriorityViewModel();

        [Display(Name = "Priorytet")]
        [Required(ErrorMessage = "Musisz wybrać priorytet wymagania")]
        public string ReturnPriority { get; set; }

        public PriorityViewModel PriorityList
        {
            get { return pvm;  }
        }

        [Display(Name = "Opis")]
        public string Description { get; set; }
        [Display(Name = "Warunki początkowe")]
        public string InitConditions { get; set; }
        [Display(Name = "Warunki końcowe")]
        public string FinalConditions { get; set; }

        // ukryty parametr w formularzu
        public string ProjectName { get; set;  }

        public void CompleteFromForm(FormCollection fc)
        {
            Name = fc["Name"];
            Actors = fc["Actors"];
            Description = fc["Description"];
            InitConditions = fc["InitConditions"];
            FinalConditions = fc["FinalConditions"];
        }

        public static FunctionalRequirement Convert(FormCollection fc, int projectId, int userId)
        {
            FunctionalRequirement fr = new FunctionalRequirement();
            fr.Name = fc["Name"];
            fr.Description = fc["Description"];
            fr.FinalConditions = fc["FinalConditions"];
            fr.InitConditions = fc["InitConditions"];
            fr.Priority = (byte)PriorityViewModel.ConvertFromString(fc["ReturnPriority"]);
            fr.Actors = fc["Actors"];
            fr.ProjectId = projectId;
            fr.AuthorId = userId;
            fr.DateOfCreate = DateTime.Now;
            fr.DateOfLastModification = DateTime.Now;
            return fr;
        }

        public static List<Scenario> MakeScenariosFromForm(FormCollection fc, int requirementId,int minId)
        {
            List<Scenario> scenarios = new List<Scenario>();
            CompleteScenarios(scenarios,fc,"",requirementId,ref minId);
            return scenarios;

        }

        private static void CompleteScenarios(List<Scenario> scenarios, FormCollection fc, string prefix, int requirementId, ref int minId, int parentId=-1)
        {
            bool added=true;
            int numberInBase = 1;
            int number=1;
            char letter='A';
            bool checkNumber=true;
            string newValue;
            string newKey;
            if (prefix!="" && Char.IsNumber(prefix[prefix.Length-1])) // jesli ostani znak prefiksu jest liczbą szukamy liter
                checkNumber=false;
            while(added)
            {
                added=false;
                if (checkNumber)
                    newKey = prefix + number.ToString();
                else
                    newKey = prefix + letter.ToString();
                newValue = fc[newKey];
                if (newValue != null)
                {
                    Scenario scenario = CreateScenario(requirementId,minId,newValue,parentId,numberInBase);
                    minId++;
                    scenarios.Add(scenario);
                    CompleteScenarios(scenarios, fc, newKey, requirementId, ref minId, minId-1);
                    added = true;
                    IncrementIndex(checkNumber, ref number, ref letter, ref numberInBase);
                }
            }
        }

        private static Scenario CreateScenario(int requirementId,int id, string value, int parentId, int number)
        {
            Scenario scenario = new Scenario();
            scenario.Id = id;
            scenario.Number = number;
            scenario.FunctionalRequirementId = requirementId;
            scenario.Text = value;
            if (parentId != -1)
                scenario.ParentId = parentId;
            else
                scenario.ParentId = null;
            return scenario;
        }

        private static void IncrementIndex(bool checkNumber,ref int number, ref char letter, ref int numberInBase)
        {
            if (checkNumber)
                number++;
            else
                letter=(char)((int)letter + 1);
            numberInBase++;
        }
    }
}